home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % This is a rough approximation to the algorithm presented in:
- %
- % "An Algorithm for NAND Decomposition Under Network Constraints,"
- % IEEE Trans. Comp., vol C-18, no. 12, Dec. 1969, p. 1098
- % by E. S. Davidson.
- %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- %
- % I have used the paper's terminology for names used in the program.
- %
- % The data structure for representing functions and variables is
- % function(FunctionNumber, TrueSet, FalseSet,
- % ConceivableInputs,
- % ImmediatePredecessors, ImmediateSuccessors,
- % Predecessors, Successors)
- %
- %
- % Common names used in the program:
- %
- % NumVars number of variables (signal inputs)
- % NumGs current number of variables and functions
- % Gs list of variable and function data
- % Gi,Gj,Gk,Gl individual variable or function--letter corresponds to
- % the subscript in the paper (most of the time)
- % Vector,V vector from a function's true set
- %
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- main :- main(0).
-
- main(N) :-
- init_state(N, NumVars, NumGs, Gs),
- add_necessary_functions(NumVars, NumGs, Gs, NumGs2, Gs2),
- test_bounds(NumVars, NumGs2, Gs2),
- search(NumVars, NumGs2, Gs2).
- main(_) :-
- write('Search completed'), nl.
-
- % Test input
- % init_state(circuit(NumInputs, NumOutputs, FunctionList))
- init_state(0, 2, 3, [ % 2 input xor
- function(2, [1,2], [0,3], [], [], [], [], []),
- function(1, [2,3], [0,1], [], [], [], [], []),
- function(0, [1,3], [0,2], [], [], [], [], [])
- ]) :-
- update_bounds(_, 100, _).
- init_state(1, 3, 4, [ % carry circuit
- function(3, [3,5,6,7], [0,1,2,4], [], [], [], [], []),
- function(2, [4,5,6,7], [0,1,2,3], [], [], [], [], []),
- function(1, [2,3,6,7], [0,1,4,5], [], [], [], [], []),
- function(0, [1,3,5,7], [0,2,4,6], [], [], [], [], [])
- ]) :-
- update_bounds(_, 100, _).
- init_state(2, 3, 4, [ % example in paper
- function(3, [1,2,4,6,7], [0,3,5], [], [], [], [], []),
- function(2, [4,5,6,7], [0,1,2,3], [], [], [], [], []),
- function(1, [2,3,6,7], [0,1,4,5], [], [], [], [], []),
- function(0, [1,3,5,7], [0,2,4,6], [], [], [], [], [])
- ]) :-
- update_bounds(_, 100, _).
- init_state(3, 3, 4, [ % sum (3 input xor)
- function(3, [1,2,4,7], [0,3,5,6], [], [], [], [], []),
- function(2, [4,5,6,7], [0,1,2,3], [], [], [], [], []),
- function(1, [2,3,6,7], [0,1,4,5], [], [], [], [], []),
- function(0, [1,3,5,7], [0,2,4,6], [], [], [], [], [])
- ]) :-
- update_bounds(_, 100, _).
- init_state(4, 3, 5, [ % do sum and carry together
- function(4, [3,5,6,7], [0,1,2,4], [], [], [], [], []),
- function(3, [1,2,4,7], [0,3,5,6], [], [], [], [], []),
- function(2, [4,5,6,7], [0,1,2,3], [], [], [], [], []),
- function(1, [2,3,6,7], [0,1,4,5], [], [], [], [], []),
- function(0, [1,3,5,7], [0,2,4,6], [], [], [], [], [])
- ]) :-
- update_bounds(_, 100, _).
- init_state(5, 5, 8, [ % 2 bit full adder
- function(7, % A2 (output)
- [1,3,4,6,9,11,12,14,16,18,21,23,24,26,29,31],
- [0,2,5,7,8,10,13,15,17,19,20,22,25,27,28,30],
- [], [], [], [], []),
- function(6, % B2 (output)
- [2,3,5,6,8,9,12,15,17,18,20,21,24,27,30,31],
- [0,1,4,7,10,11,13,14,16,19,22,23,25,26,28,29],
- [], [], [], [], []),
- function(5, % carry-out (output)
- [7,10,11,13,14,15,19,22,23,25,26,27,28,29,30,31],
- [0,1,2,3,4,5,6,8,9,12,16,17,18,20,21,24],
- [], [], [], [], []),
- function(4, % carry-in
- [16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31],
- [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15],
- [], [], [], [], []),
- function(3, % B1 input
- [8,9,10,11,12,13,14,15,24,25,26,27,28,29,30,31],
- [0,1,2,3,4,5,6,7,16,17,18,19,20,21,22,23],
- [], [], [], [], []),
- function(2, % B0 input
- [4,5,6,7,12,13,14,15,20,21,22,23,28,29,30,31],
- [0,1,2,3,8,9,10,11,16,17,18,19,24,25,26,27],
- [], [], [], [], []),
- function(1, % A1 input
- [2,3,6,7,10,11,14,15,18,19,22,23,26,27,30,31],
- [0,1,4,5,8,9,12,13,16,17,20,21,24,25,28,29],
- [], [], [], [], []),
- function(0, % A0 input
- [1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31],
- [0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30],
- [], [], [], [], [])
- ]) :-
- update_bounds(_, 21, _).
-
-
- % Iterate over all the TRUE vectors that need to be covered.
- % If no vectors remain to be covered (select_vector fails), then
- % the circuit is complete (printout results, update bounds, and
- % continue search for a lower cost circuit).
- search(NumVars, NumGsIn, GsIn) :-
- select_vector(NumVars, NumGsIn, GsIn, Gj, Vector), !,
- cover_vector(NumVars, NumGsIn, GsIn, Gj, Vector, NumGs, Gs),
- add_necessary_functions(NumVars, NumGs, Gs, NumGsOut, GsOut),
- test_bounds(NumVars, NumGsOut, GsOut),
- search(NumVars, NumGsOut, GsOut).
- search(NumVars, NumGs, Gs) :-
- output_results(NumVars, NumGs, Gs),
- update_bounds(NumVars, NumGs, Gs),
- fail.
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Given the current solution, pick the best uncovered TRUE vector
- % for covering next.
- % The selected vector is specified by its vector number and function.
- % Select_vector fails if all TRUE vectors are covered.
- % Select_vector is determinant (gives only one solution).
- select_vector(NumVars, NumGs, Gs, Gj, Vector) :-
- select_vector(Gs, NumVars, NumGs, Gs,
- dummy, 0, nf, 999, Gj, Vector, Type, _), !,
- \+ Type = cov,
- \+ Type = nf.
-
- % loop over functions
- select_vector([Gk|_], NumVars, _, _, Gj, V, Type, N, Gj, V, Type, N) :-
- function_number(Gk, K),
- K < NumVars.
- select_vector([Gk|Gks], NumVars, NumGs, Gs,
- GjIn, Vin, TypeIn, Nin, GjOut, Vout, TypeOut, Nout) :-
- function_number(Gk, K),
- K >= NumVars,
- true_set(Gk, Tk),
- select_vector(Tk, Gk, NumVars, NumGs, Gs,
- GjIn, Vin, TypeIn, Nin, Gj, V, Type, N),
- select_vector(Gks, NumVars, NumGs, Gs,
- Gj, V, Type, N, GjOut, Vout, TypeOut, Nout).
-
- % loop over vectors
- select_vector([], _, _, _, _, Gj, V, Type, N, Gj, V, Type, N).
- select_vector([V|Vs], Gk, NumVars, NumGs, Gs,
- GjIn, Vin, TypeIn, Nin, GjOut, Vout, TypeOut, Nout) :-
- vector_cover_type(NumVars, Gs, Gk, V, Type, N),
- best_vector(GjIn, Vin, TypeIn, Nin,
- Gk, V, Type, N,
- Gj2, V2, Type2, N2),
- select_vector(Vs, Gk, NumVars, NumGs, Gs,
- Gj2, V2, Type2, N2, GjOut, Vout, TypeOut, Nout).
-
- vector_cover_type(NumVars, Gs, Gj, Vector, Type, NumCovers) :-
- immediate_predecessors(Gj, IPs),
- conceivable_inputs(Gj, CIs),
- false_set(Gj, Fj),
- cover_type1(IPs, Gs, Vector, nf, 0, T, N),
- cover_type2(CIs, Gs, NumVars, Fj, Vector, T, N, Type, NumCovers).
-
- cover_type1([], _, _, T, N, T, N).
- cover_type1([I|IPs], Gs, V, TypeIn, Nin, TypeOut, Nout) :-
- function(I, Gs, Gi),
- true_set(Gi, Ti),
- \+ set_member(V, Ti), !,
- false_set(Gi, Fi),
- (set_member(V, Fi) ->
- max_type(TypeIn, cov, Type);
- max_type(TypeIn, exp, Type)),
- N is Nin + 1,
- cover_type1(IPs, Gs, V, Type, N, TypeOut, Nout).
- cover_type1([_|IPs], Gs, V, TypeIn, Nin, TypeOut, Nout) :-
- cover_type1(IPs, Gs, V, TypeIn, Nin, TypeOut, Nout).
-
- cover_type2([], _, _, _, _, T, N, T, N).
- cover_type2([I|CIs], Gs, NumVars, Fj, V, TypeIn, Nin, TypeOut, Nout) :-
- I < NumVars,
- function(I, Gs, Gi),
- false_set(Gi, Fi),
- set_member(V, Fi), !,
- max_type(TypeIn, var, Type),
- N is Nin + 1,
- cover_type2(CIs, Gs, NumVars, Fj, V, Type, N, TypeOut, Nout).
- cover_type2([I|CIs], Gs, NumVars, Fj, V, TypeIn, Nin, TypeOut, Nout) :-
- I >= NumVars,
- function(I, Gs, Gi),
- true_set(Gi, Ti),
- \+ set_member(V, Ti), !,
- false_set(Gi, Fi),
- (set_member(V, Fi) ->
- (set_subset(Fj, Ti) ->
- max_type(TypeIn, fcn, Type);
- max_type(TypeIn, mcf, Type));
- (set_subset(Fj, Ti) ->
- max_type(TypeIn, exf, Type);
- max_type(TypeIn, exmcf, Type))),
- N is Nin + 1,
- cover_type2(CIs, Gs, NumVars, Fj, V, Type, N, TypeOut, Nout).
- cover_type2([_|CIs], Gs, NumVars, Fj, V, TypeIn, Nin, TypeOut, Nout) :-
- cover_type2(CIs, Gs, NumVars, Fj, V, TypeIn, Nin, TypeOut, Nout).
-
- % The best vector to cover is the one with worst type, or, if types
- % are equal, with the least number of possible covers.
- best_vector(dummy, _, _, _, Gj2, V2, Type2, N2, Gj2, V2, Type2, N2) :- !.
- best_vector(Gj1, V1, Type1, N1, dummy, _, _, _, Gj1, V1, Type1, N1) :- !.
- best_vector(Gj1, V1, Type, N1, Gj2, _, Type, N2, Gj1, V1, Type, N1) :-
- function_number(Gj1, J), function_number(Gj2, J),
- N1 < N2, !.
- best_vector(Gj1, _, Type, N1, Gj2, V2, Type, N2, Gj2, V2, Type, N2) :-
- function_number(Gj1, J), function_number(Gj2, J),
- N1 >= N2, !.
- best_vector(Gj1, V1, Type, N1, Gj2, _, Type, _, Gj1, V1, Type, N1) :-
- (Type = exp ; Type = var),
- function_number(Gj1, J1), function_number(Gj2, J2),
- J1 > J2, !.
- best_vector(Gj1, _, Type, _, Gj2, V2, Type, N2, Gj2, V2, Type, N2) :-
- (Type = exp ; Type = var),
- function_number(Gj1, J1), function_number(Gj2, J2),
- J1 < J2, !.
- best_vector(Gj1, V1, Type, N1, Gj2, _, Type, _, Gj1, V1, Type, N1) :-
- \+ (Type = exp ; Type = var),
- function_number(Gj1, J1), function_number(Gj2, J2),
- J1 < J2, !.
- best_vector(Gj1, _, Type, _, Gj2, V2, Type, N2, Gj2, V2, Type, N2) :-
- \+ (Type = exp ; Type = var),
- function_number(Gj1, J1), function_number(Gj2, J2),
- J1 > J2, !.
- best_vector(Gj1, V1, Type1, N1, _, _, Type2, _, Gj1, V1, Type1, N1) :-
- type_order(Type2, Type1), !.
- best_vector(_, _, Type1, _, Gj2, V2, Type2, N2, Gj2, V2, Type2, N2) :-
- type_order(Type1, Type2), !.
-
- max_type(T1, T2, T1) :- type_order(T1, T2), !.
- max_type(T1, T2, T2) :- \+ type_order(T1, T2), !.
-
- % Order of types
-
- type_order(cov, exp).
- type_order(cov, var).
- type_order(cov, fcn).
- type_order(cov, mcf).
- type_order(cov, exf).
- type_order(cov, exmcf).
- type_order(cov, nf).
- type_order(exp, var).
- type_order(exp, fcn).
- type_order(exp, mcf).
- type_order(exp, exf).
- type_order(exp, exmcf).
- type_order(exp, nf).
- type_order(var, fcn).
- type_order(var, mcf).
- type_order(var, exf).
- type_order(var, exmcf).
- type_order(var, nf).
- type_order(fcn, mcf).
- type_order(fcn, exf).
- type_order(fcn, exmcf).
- type_order(fcn, nf).
- type_order(mcf, exf).
- type_order(mcf, exmcf).
- type_order(mcf, nf).
- type_order(exf, exmcf).
- type_order(exf, nf).
- type_order(exmcf, nf).
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % Cover_vector will cover the specified vector and
- % generate new circuit information.
- % Using backtracking, all possible coverings are generated.
- % The ordering of the possible coverings is approximately that
- % given in Davidson's paper, but has been simplified.
-
- cover_vector(NumVars, NumGsIn, GsIn, Gj, Vector, NumGsOut, GsOut) :-
- immediate_predecessors(Gj, IPs),
- conceivable_inputs(Gj, CIs),
- vector_types(Type),
- cover_vector(Type, IPs, CIs, Gj, Vector, NumVars, NumGsIn, GsIn,
- NumGsOut, GsOut).
-
- vector_types(var).
- vector_types(exp).
- vector_types(fcn).
- vector_types(mcf).
- vector_types(exf).
- vector_types(exmcf).
- vector_types(nf).
-
- cover_vector(exp, [I|_], _, Gj, V, _, NumGs, GsIn, NumGs, GsOut) :-
- function(I, GsIn, Gi),
- true_set(Gi, Ti),
- \+ set_member(V, Ti),
- update_circuit(GsIn, Gi, Gj, V, GsIn, GsOut).
- cover_vector(exp, [_|IPs], _, Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- cover_vector(exp, IPs, _, Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut).
- cover_vector(var, _, [I|_], Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- I < NumVars,
- function(I, GsIn, Gi),
- false_set(Gi, Fi),
- set_member(V, Fi),
- update_circuit(GsIn, Gi, Gj, V, GsIn, GsOut).
- cover_vector(var, _, [_|CIs], Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- cover_vector(var, _, CIs, Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut).
- cover_vector(fcn, _, [I|_], Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- I >= NumVars,
- function(I, GsIn, Gi),
- false_set(Gi, Fi),
- set_member(V, Fi),
- true_set(Gi, Ti),
- false_set(Gj, Fj),
- set_subset(Fj, Ti),
- update_circuit(GsIn, Gi, Gj, V, GsIn, GsOut).
- cover_vector(fcn, _, [_|CIs], Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- cover_vector(fcn, _, CIs, Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut).
- cover_vector(mcf, _, [I|_], Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- I >= NumVars,
- function(I, GsIn, Gi),
- false_set(Gi, Fi),
- set_member(V, Fi),
- true_set(Gi, Ti),
- false_set(Gj, Fj),
- \+ set_subset(Fj, Ti),
- update_circuit(GsIn, Gi, Gj, V, GsIn, GsOut).
- cover_vector(mcf, _, [_|CIs], Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- cover_vector(mcf, _, CIs, Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut).
- cover_vector(exf, _, [I|_], Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- I >= NumVars,
- function(I, GsIn, Gi),
- false_set(Gi, Fi),
- \+ set_member(V, Fi),
- true_set(Gi, Ti),
- \+ set_member(V, Ti),
- false_set(Gj, Fj),
- set_subset(Fj, Ti),
- update_circuit(GsIn, Gi, Gj, V, GsIn, GsOut).
- cover_vector(exf, _, [_|CIs], Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- cover_vector(exf, _, CIs, Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut).
- cover_vector(exmcf, _, [I|_], Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- I >= NumVars,
- function(I, GsIn, Gi),
- false_set(Gi, Fi),
- \+ set_member(V, Fi),
- true_set(Gi, Ti),
- \+ set_member(V, Ti),
- false_set(Gj, Fj),
- \+ set_subset(Fj, Ti),
- update_circuit(GsIn, Gi, Gj, V, GsIn, GsOut).
- cover_vector(exmcf, _, [_|CIs], Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut) :-
- cover_vector(exmcf, _, CIs, Gj, V, NumVars, NumGs, GsIn, NumGs, GsOut).
- cover_vector(nf, _, _, Gj, V, NumVars, NumGsIn, GsIn, NumGsOut, GsOut) :-
- NumGsOut is NumGsIn + 1,
- false_set(Gj, Fj),
- new_function_CIs(GsIn,
- function(NumGsIn,Fj,[V],[],[],[],[],[]),
- NumVars, Gs, Gi),
- update_circuit(Gs, Gi, Gj, V, Gs, GsOut).
-
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- update_circuit([], _, _, _, _, []).
- update_circuit([function(K,Tk,Fk,CIk,IPk,ISk,Pk,Sk)|GsIn],
- Gi, Gj, V, Gs,
- [function(K,Tko,Fko,CIko,IPko,ISko,Pko,Sko)|GsOut]) :-
- Gi = function(I,_,Fi,_,IPi,ISi,Pi,_),
- Gj = function(J,_,Fj,_,_,_,_,Sj),
- set_union([I], Pi, PiI),
- set_union([J], Sj, SjJ),
- (K = J ->
- set_union(Tk, Fi, Tk2);
- Tk2 = Tk),
- (K = I ->
- set_union(Tk2, Fj, Tk3);
- Tk3 = Tk2),
- ((set_member(K, IPi); set_member(K, ISi)) ->
- set_union(Tk3, [V], Tko);
- Tko = Tk3),
- (K = I ->
- set_union(Fk, [V], Fko);
- Fko = Fk),
- ((set_member(K, Pi); K = I) ->
- set_difference(CIk, SjJ, CIk2);
- CIk2 = CIk),
- ((set_member(I, CIk), set_member(V, Fk)) ->
- set_difference(CIk2, [I], CIk3);
- CIk3 = CIk2),
- (K = I ->
- exclude_if_vector_in_false_set(CIk3, Gs, V, CIk4);
- CIk4 = CIk3),
- (K = J ->
- set_difference(CIk4, [I], CIko);
- CIko = CIk4),
- (K = J ->
- set_union(IPk, [I], IPko);
- IPko = IPk),
- (K = I ->
- set_union(ISk, [J], ISko);
- ISko = ISk),
- (set_member(K, SjJ) ->
- set_union(Pk, PiI, Pko);
- Pko = Pk),
- (set_member(K, PiI) ->
- set_union(Sk, SjJ, Sko);
- Sko = Sk),
- update_circuit(GsIn, Gi, Gj, V, Gs, GsOut).
-
- exclude_if_vector_in_false_set([], _, _, []).
- exclude_if_vector_in_false_set([K|CIsIn], Gs, V, CIsOut) :-
- function(K, Gs, Gk),
- false_set(Gk, Fk),
- set_member(V, Fk), !,
- exclude_if_vector_in_false_set(CIsIn, Gs, V, CIsOut).
- exclude_if_vector_in_false_set([K|CIsIn], Gs, V, [K|CIsOut]) :-
- exclude_if_vector_in_false_set(CIsIn, Gs, V, CIsOut).
-
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- add_necessary_functions(NumVars, NumGsIn, GsIn, NumGsOut, GsOut) :-
- add_necessary_functions(NumVars, NumVars, NumGsIn, GsIn,
- NumGsOut, GsOut).
-
- add_necessary_functions(NumGs, _, NumGs, Gs, NumGs, Gs) :- !.
- add_necessary_functions(K, NumVars, NumGsIn, GsIn, NumGsOut, GsOut) :-
- function(K, GsIn, Gk),
- function_type(NumVars, NumGsIn, GsIn, Gk, nf, V), !,
- false_set(Gk, Fk),
- new_function_CIs(GsIn,
- function(NumGsIn,Fk,[V],[],[],[],[],[]),
- NumVars, Gs, Gl),
- function(K, Gs, Gk1),
- update_circuit(Gs, Gl, Gk1, V, Gs, Gs1),
- NumGs1 is NumGsIn + 1,
- K1 is K + 1,
- add_necessary_functions(K1, NumVars, NumGs1, Gs1, NumGsOut, GsOut).
- add_necessary_functions(K, NumVars, NumGsIn, GsIn, NumGsOut, GsOut) :-
- K1 is K + 1,
- add_necessary_functions(K1, NumVars, NumGsIn, GsIn, NumGsOut, GsOut).
-
- new_function_CIs(GsIn, function(L,Tl,Fl,_,IPl,ISl,Pl,Sl), NumVars,
- [GlOut|GsOut], GlOut) :-
- new_function_CIs(GsIn, L, Fl, NumVars, GsOut, [], CIlo),
- GlOut = function(L,Tl,Fl,CIlo,IPl,ISl,Pl,Sl).
-
- new_function_CIs([], _, _, _, [], CIl, CIl).
- new_function_CIs([function(K,Tk,Fk,CIk,IPk,ISk,Pk,Sk)|GsIn], L, Fl, NumVars,
- [function(K,Tk,Fk,CIko,IPk,ISk,Pk,Sk)|GsOut], CIlIn, CIlOut) :-
- set_intersection(Fl, Fk, []), !,
- (K >= NumVars ->
- set_union(CIk, [L], CIko);
- CIko = CIk),
- new_function_CIs(GsIn, L, Fl, NumVars, GsOut, [K|CIlIn], CIlOut).
- new_function_CIs([Gk|GsIn], L, Fl, NumVars, [Gk|GsOut], CIlIn, CIlOut) :-
- new_function_CIs(GsIn, L, Fl, NumVars, GsOut, CIlIn, CIlOut).
-
- function_type(NumVars, NumGs, Gs, Gk, Type, Vector) :-
- true_set(Gk, Tk),
- select_vector(Tk, Gk, NumVars, NumGs, Gs,
- dummy, 0, nf, 999, _, Vector, Type, _).
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Cost and constraint predicates:
-
- % very simple bound for now
-
- test_bounds(_, NumGs, _) :-
- access(0, Bound),
- NumGs < Bound.
-
- update_bounds(_, NumGs, _) :-
- set(0, NumGs).
-
- % set and access for systems that don't support them
-
- %:- dynamic '$set'/2.
- %set(N, A) :- (retract('$set'(N, _)); true), assert('$set'(N, A)), !.
- %access(N, A) :- '$set'(N,A), !.
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Output predicates:
-
- % for now just dump everything
-
- output_results(NumVars, NumGs, Gs) :-
- NumGates is NumGs - NumVars,
- write(NumGates), write(' gates'), nl,
- write_gates(Gs), nl.
-
- write_gates([]).
- write_gates([Gi|Gs]) :-
- function_number(Gi, I),
- write('gate #'), write(I), write(' inputs: '),
- immediate_predecessors(Gi, IPi),
- write(IPi), nl,
- write_gates(Gs).
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- % Retrieve the specified function from the function list.
- % function(FunctionNumber, FunctionList, Function).
- function(I, [Gi|_], Gi) :- function_number(Gi, I), !.
- function(I, [_|Gs], Gi) :- function(I, Gs, Gi).
-
- function_number( function(I,_,_,_,_,_,_,_), I).
- true_set( function(_,T,_,_,_,_,_,_), T).
- false_set( function(_,_,F,_,_,_,_,_), F).
- conceivable_inputs( function(_,_,_,CI,_,_,_,_), CI).
- immediate_predecessors( function(_,_,_,_,IP,_,_,_), IP).
- immediate_successors( function(_,_,_,_,_,IS,_,_), IS).
- predecessors( function(_,_,_,_,_,_,P,_), P).
- successors( function(_,_,_,_,_,_,_,S), S).
-
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- % Set operations assume that the sets are represented by an ordered list
- % of integers.
-
- set_union([], [], []).
- set_union([], [X|L2], [X|L2]).
- set_union([X|L1], [], [X|L1]).
- set_union([X|L1], [X|L2], [X|L3]) :- set_union(L1, L2, L3).
- set_union([X|L1], [Y|L2], [X|L3]) :- X < Y, set_union(L1, [Y|L2], L3).
- set_union([X|L1], [Y|L2], [Y|L3]) :- X > Y, set_union([X|L1], L2, L3).
-
- set_intersection([], [], []).
- set_intersection([], [_|_], []).
- set_intersection([_|_], [], []).
- set_intersection([X|L1], [X|L2], [X|L3]) :- set_intersection(L1, L2, L3).
- set_intersection([X|L1], [Y|L2], L3) :- X < Y, set_intersection(L1, [Y|L2], L3).
- set_intersection([X|L1], [Y|L2], L3) :- X > Y, set_intersection([X|L1], L2, L3).
-
- set_difference([], [], []).
- set_difference([], [_|_], []).
- set_difference([X|L1], [], [X|L1]).
- set_difference([X|L1], [X|L2], L3) :- set_difference(L1, L2, L3).
- set_difference([X|L1], [Y|L2], [X|L3]) :- X < Y, set_difference(L1, [Y|L2], L3).
- set_difference([X|L1], [Y|L2], L3) :- X > Y, set_difference([X|L1], L2, L3).
-
- set_subset([], _).
- set_subset([X|L1], [X|L2]) :- set_subset(L1, L2).
- set_subset([X|L1], [Y|L2]) :- X > Y, set_subset([X|L1], L2).
-
- set_member(X, [X|_]).
- set_member(X, [Y|T]) :- X > Y, set_member(X, T).
-